function net=vggFCN_fc678_mLoss_split()
%精简结构 在16s和8s上不添加任何sum操作！！
net= dagnn.DagNN;
fD = [64, 128, 256, 512, 512, 4096];
C=21;

iv_name='input';
[net,ov_name]=bn_relu_conv(net,iv_name,'conv1_1', 3,fD(1), 3, 0,1);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv1_2', fD(1),fD(1), 3, 0,1);iv_name=ov_name;

[net,ov_name]=transition(net,iv_name,'pool1',0);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv2_1', fD(1),fD(2), 3, 0,1);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv2_2', fD(2),fD(2), 3, 0,1);iv_name=ov_name;

[net,ov_name]=transition(net,iv_name,'pool2',0);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv3_1', fD(2),fD(3), 3, 0,1);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv3_2', fD(3),fD(3), 3, 0,1);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv3_3', fD(3),fD(3), 3, 0,1);iv_name=ov_name;

[net,ov_name]=transition(net,iv_name,'pool3',0);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv4_1', fD(3),fD(4), 3, 0,1);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv4_2', fD(4),fD(4), 3, 0,1);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv4_3', fD(4),fD(4), 3, 0,1);iv_name=ov_name;conv4=ov_name;


[net,ov_name]=transition(net,iv_name,'pool4',0);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv5_1', fD(4),fD(5), 3, 0,1);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv5_2', fD(5),fD(5), 3, 0,1);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv5_3', fD(5),fD(5), 3, 0,1);iv_name=ov_name;conv5=ov_name;

[net,ov_name]=transition(net,iv_name,'pool5',0);iv_name=ov_name;
[net,ov_name]=bn_relu_conv(net,iv_name,'conv6_1', fD(5),fD(6), 7, 0,3);iv_name=ov_name;%fc6
[net,ov_name]=bn_relu_conv(net,iv_name,'conv6_2', fD(6),fD(6), 1, 0,0);iv_name=ov_name;conv6=ov_name;

CC=[210,210,210];
%1
layername='conv6_3'; ov_name=layername;iv_name=conv6;
param={[layername,'_conv_kernel'],[layername,'_conv_bias']};
net.addLayer(layername, dagnn.Conv('size', [1,1,fD(6),CC(1)]), iv_name,ov_name, param);
iv_name=ov_name;
[net,ov_name] =addsplitLayer(net,CC(1),C,iv_name,'from32s');

up5=32;iv_name=ov_name;
deconvBlock5=dagnn.ConvTranspose('size', [up5,up5,1,C],'numGroups', C, 'upsample', up5, 'hasBias',false);
net.addLayer('prediction', deconvBlock5, iv_name, 'prediction', 'upconv_pm') ;

%2
layername='bridge5'; ov_name=layername; iv_name=conv5;
param={[layername,'_kernel'],[layername,'_bias']};       
net.addLayer(layername, dagnn.Conv('size', [1,1,fD(5),CC(2)]), iv_name,ov_name, param);
iv_name=ov_name;
[net,ov_name] =addsplitLayer(net,CC(2),C,iv_name,'from16s');

up4=16;iv_name=ov_name;
deconvBlock4=dagnn.ConvTranspose('size', [up4,up4,1,C],'numGroups',C,'upsample', up4,'hasBias',false);
net.addLayer('prediction4', deconvBlock4, iv_name, 'prediction4', 'prediction4_pm') ;

%3
layername='bridge4'; ov_name=layername; iv_name=conv4;
param={[layername,'_kernel'],[layername,'_bias']};       
net.addLayer(layername, dagnn.Conv('size', [1,1,fD(4),CC(3)]), iv_name,ov_name, param);
iv_name=ov_name;
[net,ov_name] =addsplitLayer(net,CC(3),C,iv_name,'from8s');

up3=8;iv_name=ov_name;
deconvBlock3=dagnn.ConvTranspose('size', [up3,up3,1,C],'numGroups',C,'upsample', up3, 'hasBias',false);
net.addLayer('prediction3', deconvBlock3, iv_name, 'prediction3', 'prediction3_pm') ;


% ori prediction1,2,3 represents scale!!
net.addLayer('objective', Segmentation_mLoss(),    {'label', 'prediction','prediction4','prediction3'}, 'objective') ;
% net.addLayer('objective', SegmentationLoss('loss', 'softmaxlog'), {'prediction', 'label'}, 'objective') ;
net.addLayer('accuracy',  Segmentation_mAccuracy(), {'label','prediction','prediction4','prediction3'}, 'accuracy') ;
net.initParams();


    function [net,ov_name]=bn_relu_conv(net,iv_name,ov_name_pre,channel1,channel2,filter_size,dropout,pad_size)
        convBlock = dagnn.Conv('size', [filter_size,filter_size,channel1,channel2], 'pad', [pad_size,pad_size,pad_size,pad_size],'stride', [1,1], 'hasBias', true);
        net.addLayer([ov_name_pre,'_conv'],convBlock,iv_name,[ov_name_pre,'_conv'],{[ov_name_pre,'_conv_kernel'],[ov_name_pre,'_conv_bias']});
        net.addLayer([ov_name_pre,'_relu'],dagnn.ReLU(),[ov_name_pre,'_conv'], [ov_name_pre,'_relu'],{});
        ov_name=[ov_name_pre,'_relu'];
    end
    function [net,ov_name]=transition(net,iv_name,ov_name_pre,dropout)
        %2 pooling method also influence!!!
        %3 pad's size!!!
        poolBlock = dagnn.Pooling('method', 'max', 'poolSize', [2 2], 'stride', [2,2], 'pad',[0,1,0,1]);
        net.addLayer([ov_name_pre,'_pool'], poolBlock, {iv_name},{[ov_name_pre,'_pool']},{});
        ov_name=[ov_name_pre,'_pool'];
    end
end